/**********************************************************************************************/
/* FBL_Type_Traits.h                                                      					  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006															  */
/* All Rights Reserved                                                   					  */
/**********************************************************************************************/

#ifndef _FBL_Type_Traits_h 
	#define _FBL_Type_Traits_h
#pragma once

// FBL:
#include <VShared/FBL/publ/Headers/FBL.h>
#include <VShared/FBL/publ/Util_Strings/FBL_String_Len_Const.h>
#include <VShared/FBL/publ/Util_Strings/FBL_ustdio.h>
#include <VShared/FBL/publ/Util_Strings/FBL_UnicodeToFromNumeric.h>
#include <VShared/FBL/publ/Utilities/FBL_ByteSwap.h>
#include <VShared/FBL/publ/Interfaces/FBL_I_VNETW_Packet.h>

// STD:
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

// FINAL:
#include <VShared/FBL/publ/Headers/FBL_pre_header.h>

#pragma warning(disable : 4996)


/**********************************************************************************************/
FBL_Begin_Namespace

// Helpers:

/**********************************************************************************************/
inline bool IsTrueStr( const char* inString )
{
	return( (inString[0] == 'T' || inString[0] == 't') &&	
			 (inString[1] == 'R' || inString[1] == 'r') &&
			 (inString[2] == 'U' || inString[2] == 'u') &&
			 (inString[3] == 'E' || inString[3] == 'e') );
}


/**********************************************************************************************/
inline bool IsTrueStr( const UChar* inString )
{
	return( (inString[0] == UChar('T') || inString[0] == UChar('t')) &&	
			(inString[1] == UChar('R') || inString[1] == UChar('r')) &&
			(inString[2] == UChar('U') || inString[2] == UChar('u')) &&
			(inString[3] == UChar('E') || inString[3] == UChar('e')) );
}


/**********************************************************************************************/
// Accumulate type-specific functions.
// 
template<class T>
struct type_traits
{
	typedef T      	 		value_type;
	typedef int      	 	int_type;

static void 				assign(T& c1, const T& c2);
static value_type* 			assign(value_type* s, ulong n, value_type a);

static ulong 				length(const value_type* s);	// up to zero.
static ulong 				max_text_length( void );

static bool 				eq		(const T& c1, const T& c2);
static bool 				lt		(const T& c1, const T& c2);

static int	 				compare	(const T& c1, const T& c2);
static int	 				compare_voids(const void* c1, const void* c2);
static int 					compare(const value_type* s1, const value_type* s2, ulong n);

static void 				swap( T& v1, T& v2 );
static void 				qsort( T* first, T* last );

static const value_type* 	find(const value_type* s, ulong n, const T& a);

static value_type* 			move(value_type* s1, const value_type* s2, ulong n);
static value_type* 			copy(value_type* s1, const value_type* s2, ulong n);

static int_type 			to_int_type(const T& c);

static UChar*				to_str( const T* c1, UChar* outString );
static void					from_str( const UChar* inString, T* c1 );

static char*				to_str( const T* c1, char* outString );
static void					from_str( const char* inString, T* c1 );

static void					swap_bytes( T& t );

static void					From( 	T* outpVal, I_PacketRcv* inPacket, bool inBlock );
static void					To(  	const T* inpVal, I_PacketSnd* inPacket, bool inBlock );

};


/**********************************************************************************************/
// Implementation: type_traits<T>
//

/**********************************************************************************************/
template <class T>
inline void 
type_traits<T>::assign(T& c1, const T& c2)
{
	c1 = c2;
}

/**********************************************************************************************/
template <class T>
inline bool 
type_traits<T>::eq(const T& c1, const T& c2)
{
	return c1 == c2;
}

/**********************************************************************************************/
template <class T>
inline bool 
type_traits<T>::lt(const T& c1, const T& c2)
{
	return c1 < c2;
}

/**********************************************************************************************/
template <class T>
inline int 
type_traits<T>::compare(const T& c1, const T& c2)
{
	return eq(c1,c2) ? 0 
					 : (lt(c1,c2) ? -1 : +1);
}

/**********************************************************************************************/
template <class T>
inline int 
type_traits<T>::compare_voids(const void* c1, const void* c2)
{
	return eq( *(T*)c1, *(T*)c2) ? 0 
					 			 : (lt( *(T*)c1, *(T*)c2 ) ? -1 : +1);
}

/**********************************************************************************************/
template <class T>
inline int 
type_traits<T>::compare(const value_type* s1, const value_type* s2, ulong n)
{
	for (ulong i = 0; i < n; ++i, ++s1, ++s2)
	{
		if (lt(*s1, *s2))
			return -1;
		if (lt(*s2, *s1))
			return 1;
	}
	return 0;
}


/**********************************************************************************************/
template <class T>
inline void swap( T& v1, T& v2 )                      
{
	T tmp = v1;
	v1 = v2;
	v2 = tmp;
}


/**********************************************************************************************/
template <class T>
inline void qsort_long( T* first, T* last )                      
{
	T*	lp;
	T*	rp;
	T*	ip;
	T*	jp;
//	ulong	theTmp;
	
	if( first == last )
		return;
	
	ulong theCount = (ulong)(last - first + 1);
	
	rp = last;	
	lp = first + theCount/2;	
	
	for (;;)
	{
		if (lp > first)
			--lp; 
		else{
			Swap(lp,rp);
			
			--rp; 
			if (rp == first)
				return;
		}
			
		jp = lp;
		
		while( jp + (jp - first + 1) <= rp )
		{
			ip = jp;
			jp += jp - first + 1;	// jp *= 2; 
			
			if( jp < rp ){
				if ( *jp < *(jp+1) )
					++jp; 
			}
			
			if( *ip < *jp ){	
					swap(*ip,*jp);
			}else	break;
		}
	}
}


/**********************************************************************************************/
template <class T>
inline ulong type_traits<T>::length(const value_type* s)
{
	ulong len = 0;
	while (!eq(*s, T()))
	{
		++s;
		++len;
	}
	return len;
}

/**********************************************************************************************/
template <class T> 
inline const typename type_traits<T>::value_type*
type_traits<T>::find(const value_type* s, ulong n, const T& a)
{
	if (n == 0)
		return 0;
	const value_type* p = s;
	ulong i = 0;
	while (!eq(*p, a))
	{
		++i;
		if (i == n)
			return 0;
		++p;
	}
	return p;
}

/**********************************************************************************************/
template <class T>
inline typename type_traits<T>::value_type*
type_traits<T>::move(value_type* s1, const value_type* s2, ulong n)
{
	value_type* r = s1;
	if (s1 < s2)
	{
		for (ulong i = 0; i < n; ++i)
			assign(*s1++, *s2++);
	}
	else if (s2 < s1)
	{
		s1 += n;
		s2 += n;
		for (; n > 0; --n)
			assign(*--s1, *--s2);
	}
	return r;
}

/**********************************************************************************************/
template <class T>
inline typename type_traits<T>::value_type*
type_traits<T>::copy(value_type* s1, const value_type* s2, ulong n)
{
	value_type* r = s1;
	for (ulong i = 0; i < n; ++i)
		assign(*s1++, *s2++);
	return r;
}

/**********************************************************************************************/
template <class T>
inline typename type_traits<T>::value_type*
type_traits<T>::assign(value_type* s, ulong n, value_type a)
{
	value_type* r = s;
	for (ulong i = 0; i < n; ++i)
		assign(*s++, a);
	return r;
}


/**********************************************************************************************/
template <class T>
inline typename type_traits<T>::int_type
type_traits<T>::to_int_type(const T& c)
{
	return int_type(c);
}


#pragma mark -
#pragma mark === SPECIALIZATIONs of max_text_length() === 


/**********************************************************************************************/
template <> 
inline
ulong type_traits<bool>::max_text_length( void )
{
	return kBoolStrMaxLen;
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<uchar>::max_text_length( void )
{
	return kUCharStrMaxLen;
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<short>::max_text_length( void )
{
	return kShortStrMaxLen; 
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<ushort>::max_text_length( void )
{
	return kUShortStrMaxLen;  
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<long>::max_text_length( void )
{
	return kLongStrMaxLen;
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<ulong>::max_text_length( void )
{
	return kULongStrMaxLen;
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<llong>::max_text_length( void )
{
	return kLLongStrMaxLen; 
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<ullong>::max_text_length( void )
{
	return kULLongStrMaxLen;
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<float>::max_text_length( void )
{
	return kFloatStrMaxLen;
}


/**********************************************************************************************/
template <> 
inline
ulong type_traits<double>::max_text_length( void )
{
	return kDoubleStrMaxLen;
}


#pragma mark -
#pragma mark === SPECIALIZATION of to_str() ===


/**********************************************************************************************/
template <> 
inline
UChar* type_traits<bool>::to_str( const bool* c1, UChar* outString )
{
	char bool_str[kBoolStrMaxLen + 1];
	ulong num = (ulong) sprintf( bool_str, "%lu", (ulong) *c1 );

	vu_a2u(bool_str, outString, long(num) );

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<uchar>::to_str( const uchar* c1, UChar* outString )
{
	char uchar_str[kUCharStrMaxLen + 1];
	ulong num = (ulong) sprintf( uchar_str, "%lu", (ulong) *c1 );

	vu_a2u(uchar_str, outString, long(num) );

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<short>::to_str( const short* c1, UChar* outString )
{
	char short_str[kShortStrMaxLen + 1];
	ulong num = (ulong) sprintf( short_str, "%ld", (long) *c1 );

	vu_a2u(short_str, outString, long(num));

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<ushort>::to_str( const ushort* c1, UChar* outString )
{
	char ushort_str[kUShortStrMaxLen + 1];
	ulong num = (ulong) sprintf( ushort_str, "%lu", (ulong) *c1 );

	vu_a2u(ushort_str, outString, long(num));

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<long>::to_str( const long* c1, UChar* outString )
{
	char long_str[kLongStrMaxLen + 1];
	ulong num = (ulong) sprintf( long_str, "%ld", (long) *c1 );

	vu_a2u(long_str, outString, long(num) );

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<ulong>::to_str( const ulong* c1, UChar* outString )
{
	char ulong_str[kULongStrMaxLen + 1];
	ulong num = (ulong) sprintf( ulong_str, "%lu", *c1 );

	vu_a2u(ulong_str, outString, long(num));

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<llong>::to_str( const llong* c1, UChar* outString )
{
	char llong_str[kLLongStrMaxLen + 1];

#ifdef _MSC_VER
	tslen num = sprintf( llong_str, "%I64i", *c1 );
#else // non-Visual
	tslen num = sprintf( llong_str, "%lli", *c1 );
#endif // _MSC_VER

	vu_a2u( llong_str, outString, long(num) );

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<ullong>::to_str( const ullong* c1, UChar* outString )
{
	// PROBLEM: ICU's u_sprintf() does not handle 64-bit integers
	char ullong_str[kULLongStrMaxLen + 1];

#ifdef _MSC_VER
	tslen num = static_cast<tslen>(sprintf( ullong_str, "%I64u", *c1 ));
#else // non-Visual
	tslen num = static_cast<tslen>(sprintf( ullong_str, "%llu", *c1 ));
#endif // _MSC_VER

	vu_a2u( ullong_str, outString, num );

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<float>::to_str( const float* c1, UChar* outString )
{
	char float_str[kFloatStrMaxLen + 1];
	tslen num = static_cast<tslen>(sprintf( float_str, "%G", *c1 ));
	
	vu_a2u( float_str, outString, num );

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
UChar* type_traits<double>::to_str( const double* c1, UChar* outString )
{
	char double_str[kDoubleStrMaxLen + 1];
	tslen num = static_cast<tslen>(sprintf( double_str, "%G", *c1 ));

	vu_a2u( double_str, outString, num );

	return outString + num;
}

/**********************************************************************************************/
/*template <> 
inline
inline UChar* type_traits<ldouble>::to_str( const ldouble* c1, UChar* outString )
{
	char ldouble_str[kDoubleStrMaxLen + 1];
	ulong num = (ulong) sprintf( ldouble_str, "%G", *c1 );
	u_charsToUChars( ldouble_str, outString, kDoubleStrMaxLen + 1 );
	return outString + num;
}*/


#pragma mark -
#pragma mark === SPECIALIZATION of to_str() (ASCII) ===


/**********************************************************************************************/
template<> 
inline
char* type_traits<bool>::to_str( const bool* c1, char* outString )
{
	ulong num = (ulong)sprintf( outString, "%lu", (ulong) *c1 );
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<uchar>::to_str( const uchar* c1, char* outString )
{
	ulong num = (ulong)sprintf( outString, "%lu", (ulong)*c1 );
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<short>::to_str( const short* c1, char* outString )
{
	ulong num = (ulong) sprintf( outString, "%ld", (long) *c1 );
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<ushort>::to_str( const ushort* c1, char* outString )
{
	ulong num = (ulong)sprintf( outString, "%lu", (ulong) *c1 );
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<long>::to_str( const long* c1, char* outString )
{
	ulong num = (ulong)sprintf( outString, "%ld", (long) *c1 );
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<ulong>::to_str( const ulong* c1, char* outString )
{
	ulong num = (ulong)sprintf( outString, "%lu", *c1 );
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<llong>::to_str( const llong* c1, char* outString )
{
#ifdef _MSC_VER
	tslen num = sprintf( outString, "%I64i", *c1 );
#else // non-Visual
	tslen num = sprintf( outString, "%lli", *c1 );
#endif

	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<ullong>::to_str( const ullong* c1, char* outString )
{
#ifdef _MSC_VER
	tslen num = static_cast<tslen>(sprintf( outString, "%I64u", *c1 ));
#else // non-Visual
	tslen num = static_cast<tslen>(sprintf( outString, "%llu", *c1 ));
#endif

	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<float>::to_str( const float* c1, char* outString )
{
	tslen num = static_cast<tslen>(sprintf( outString, "%G", *c1 ));
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<double>::to_str( const double* c1, char* outString )
{
	tslen num = static_cast<tslen>(sprintf( outString, "%G", *c1 ));
	outString[num] = '\0';

	return outString + num;
}

/**********************************************************************************************/
template <> 
inline
char* type_traits<char>::to_str( const char* c1, char* outString )
{
	if( outString )
	{
		strcpy(outString, c1);

		return outString + (outString ? strlen(outString) : 0 );
	}
	else
	{
		return NULL;
	}
}


#pragma mark -
#pragma mark === SPECIALIZATION of from_str() (Unicode) ===


/**********************************************************************************************/
template <> 
inline
void type_traits<bool>::from_str( const UChar* inString, bool* c1 )
{
	if( *inString == UChar('1') )
	{ 
		*c1 = true; 
		
	}else if( IsTrueStr( inString ) ) 
	{
		*c1 = true;
	} 
	else
	{
		 *c1 = false;
	}
}

/**********************************************************************************************/
template <> 
inline
void type_traits<uchar>::from_str( const UChar* inString, uchar* c1 )
{
	*c1 = (uchar) u_utol( inString );
}

/**********************************************************************************************/
template <> 
inline
void type_traits<short>::from_str( const UChar* inString, short* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (short) 1;
	else
		*c1 = (short) u_utol( inString );
}

/**********************************************************************************************/
template <> 
inline
void type_traits<ushort>::from_str( const UChar* inString, ushort* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (ushort) 1;
	else
		*c1 = (ushort) u_utol( inString );
}

/**********************************************************************************************/
template <> 
inline
void type_traits<long>::from_str( const UChar* inString, long* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = 1;
	else
		*c1 = u_utol( inString );
}

/**********************************************************************************************/
template <> 
inline
void type_traits<ulong>::from_str( const UChar* inString, ulong* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = 1;
	else
		*c1 = u_ustoul( inString );
}

/**********************************************************************************************/
template <> 
inline
void type_traits<llong>::from_str( const UChar* inString, llong* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = 1;
	else
		*c1 = u_utoll(inString);
}

/**********************************************************************************************/
template <> 
inline
void type_traits<ullong>::from_str( const UChar* inString, ullong* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = 1;
	else
		*c1 = u_ustoull(inString);
}

/**********************************************************************************************/
template <> 
inline
void type_traits<float>::from_str( const UChar* inString, float* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (float) 1;
	else
		*c1 = (float) u_utof( inString );
}

/**********************************************************************************************/
template <> 
inline
void type_traits<double>::from_str( const UChar* inString, double* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (double) 1;
	else
		*c1 = u_utof( inString );
}


#pragma mark -
#pragma mark === ASCII versions ===


/**********************************************************************************************/
template <> 
inline
void type_traits<bool>::from_str( const char* inString, bool* c1 )
{
	if( *inString == UChar('1') )
	{ 
		*c1 = true; 
		
	}
	else if( IsTrueStr( inString ) ) 
	{
		*c1 = true;
	}  
	else
	{
		 *c1 = false;
	}
}


/**********************************************************************************************/
template<>
inline 
void type_traits<uchar>::from_str( const char* inString, uchar* c1 )
{
	*c1 = (uchar) atol( inString );
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<short>::from_str( const char* inString, short* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (short) 1;
	else
		*c1 = (short) atol( inString );
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<ushort>::from_str( const char* inString, ushort* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (ushort) 1;
	else
		*c1 = (ushort) atol( inString );
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<long>::from_str( const char* inString, long* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (long) 1;
	else
		*c1 = atol( inString );
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<ulong>::from_str( const char* inString, ulong* c1 )
{
	if( IsTrueStr( inString ) )
	{
		*c1 = (ulong) 1;
	}
	else
	{
		char* stopChar = 0;
		*c1 = strtoul(inString, &stopChar, 10);
	}
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<llong>::from_str( const char* inString, llong* c1 )
{
	if( IsTrueStr( inString ) )
	{
		*c1 = (llong) 1;
	}
	else
	{
		#if _MSC_VER

			#if _MSC_VER > 1310		
				sscanf_s(inString, "%I64i", c1);
			#else
				sscanf(inString, "%I64i", c1);
			#endif //_MSC_VER

		#else // non-Visual:

			sscanf(inString, "%lli", c1);

		#endif // _MSC_VER
	}
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<ullong>::from_str( const char* inString, ullong* c1 )
{
	if( IsTrueStr( inString ) )
	{
		*c1 = (ullong) 1;
	}
	else
	{
		#ifdef _MSC_VER

			#if _MSC_VER > 1310		
				sscanf_s(inString, "%I64u", c1);
			#else
				sscanf(inString, "%I64u", c1);
			#endif //_MSC_VER

		#else // non-Visual

			sscanf(inString, "%llu", c1);

		#endif //_MSC_VER
	}
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<float>::from_str( const char* inString, float* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (float) 1;
	else
		*c1 = static_cast<float>(atof(inString));
}

/**********************************************************************************************/
template<> 
inline 
void type_traits<double>::from_str( const char* inString, double* c1 )
{
	if( IsTrueStr( inString ) )
		*c1 = (double) 1;
	else
		*c1 = atof(inString);
}

/**********************************************************************************************/
#if U_SIZEOF_WCHAR_T == 2
template <> 
inline void type_traits<UChar>::from_str( const UChar* inString, UChar* c1 )
{
	// Since inString must be NULL terminated (???)
	// then we can simply use u_strcpy
	vu_strcpy(c1, inString);
}
#endif


#pragma mark -
#pragma mark === SPECIALIZATION of swap_bytes() ===


/**********************************************************************************************/
template <> 
inline
void type_traits<bool>::swap_bytes( bool& v )
{
	argused1(v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<uchar>::swap_bytes( uchar& v )
{
	argused1(v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<short>::swap_bytes( short& v )
{
	Swap_2_bytes(&v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ushort>::swap_bytes( ushort& v )
{
	Swap_2_bytes((short*)&v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<long>::swap_bytes( long& v )
{
	Swap_4_bytes(&v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ulong>::swap_bytes( ulong& v )
{
	Swap_4_bytes((long*)&v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<llong>::swap_bytes( llong& v )
{
	Swap_8_bytes((double*)&v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ullong>::swap_bytes( ullong& v )
{
	Swap_8_bytes((double*)&v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<float>::swap_bytes( float& v )
{
	Swap_4_bytes((long*)&v);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<double>::swap_bytes( double& v )
{
	Swap_8_bytes((double*)&v);
}


#pragma mark -
#pragma mark === SPECIALIZATION of From() ===

/**********************************************************************************************/
template <> 
inline
void type_traits<bool>::From( bool* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_BoolParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<uchar>::From( uchar* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_UCharParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<short>::From( short* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_ShortParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ushort>::From( ushort* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_UShortParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<long>::From( long* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_LongParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ulong>::From( ulong* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_ULongParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<llong>::From( llong* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_LLongParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ullong>::From( ullong* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_ULLongParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<float>::From( float* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_FloatParam();
}


/**********************************************************************************************/
template <> 
inline
void type_traits<double>::From( double* outpVal, I_PacketRcv* inPacket, bool inBlock )
{
	argused1(inBlock);
	(*outpVal) = inPacket->get_DoubleParam();
}


#pragma mark -
#pragma mark === SPECIALIZATION of To() ===

/**********************************************************************************************/
template <> 
inline
void type_traits<bool>::To( const bool* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_BoolParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<uchar>::To( const uchar* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_UCharParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<short>::To( const short* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_ShortParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ushort>::To( const ushort* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_UShortParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<long>::To( const long* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_LongParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ulong>::To( const ulong* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_ULongParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<llong>::To( const llong* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_LLongParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<ullong>::To( const ullong* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_ULLongParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<float>::To( const float* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_FloatParam(*inpVal);
}


/**********************************************************************************************/
template <> 
inline
void type_traits<double>::To( const double* inpVal, I_PacketSnd* inPacket, bool inBlock )
{
	argused1(inBlock);
	inPacket->put_DoubleParam(*inpVal);
}


#pragma mark -
#pragma mark === typedefs


/**********************************************************************************************/
typedef type_traits<bool>		bool_traits;
typedef type_traits<uchar>		byte_traits;

typedef type_traits<short>		short_traits;
typedef type_traits<ushort>		ushort_traits;

typedef type_traits<long>		long_traits;
typedef type_traits<ulong>		ulong_traits;

typedef type_traits<llong>		llong_traits;
typedef type_traits<ullong>		ullong_traits;

typedef type_traits<float>		float_traits;
typedef type_traits<double>		double_traits;

//typedef type_traits<UChar>		string_traits;
//typedef short_traits			string_traits;
typedef type_traits<uchar>		blob_traits;


/**********************************************************************************************/
FBL_End_Namespace

#include <VShared/FBL/publ/Headers/FBL_post_header.h>

#endif // _FBL_Type_Traits_h
